package youke.home.services;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.HmacUtils;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.http.*;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

@Service
public class QuKLiveService {
    private static final String API_URL = "http://api.quklive.com/cloud/open/activity/info";
    private static final String APP_KEY = "vu0klr7diqnncviq";  // 用您的实际appKey替换
    private static final String APP_SECRET = "9L4qmx3SAzT1ECN7"; // 用您的实际appSecret替换

    /**
     * 发送请求获得 new JsonNode
     */
    private JsonNode getJsonNode(Long liveId) throws IOException {
        // 设置请求头和请求体
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        // 获取时间戳
        long nonce = System.currentTimeMillis();

        // 生成签名
        String content = "appKey=" + APP_KEY + "&nonce=" + nonce;
        String signature = generateSignature(content);

        // 设置请求参数
        Map<String, Object> requestParams = new HashMap<>();
        requestParams.put("appKey", APP_KEY);
        requestParams.put("nonce", nonce);
        requestParams.put("signature", signature);
        requestParams.put("id", liveId);

        // 创建请求体
        HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestParams, headers);

        // 发送请求
        RestTemplate restTemplate = new RestTemplate();
        ResponseEntity<String> response = restTemplate.exchange(API_URL, HttpMethod.POST, entity, String.class);

        // 处理返回结果
        JsonNode jsonNode = new ObjectMapper().readTree(response.getBody());
        System.out.println(jsonNode.toString());
        return jsonNode;
    }


    /**
     * 获取直播信息，并根据 liveType 确定处理逻辑
     */
    public String getLiveInfo(long liveId) {
        try {
            JsonNode jsonNode = getJsonNode(liveId);
            if (jsonNode.get("code").asInt() == 0) {
                /**
                 * 获取 HLS 地址和 liveType
                 */
                String hlsUrl = jsonNode.get("value").get("urlGroup").get("hlsUrl").asText();
                String liveType = jsonNode.get("value").get("liveType").asText();
                System.out.println("获取的m3u8 地址: " + hlsUrl);
                simulateLiveStreamUpdates(hlsUrl, liveId);

//                if ("1".equals(liveType)) {
//                    // liveType 为 1，表示直播事件，模拟直播过程中的更新
//                    System.out.println("直播事件，多次获取一次 HLS 地址");
//                    simulateLiveStreamUpdates(hlsUrl, liveId);
//                } else if ("10".equals(liveType)) {
//                    // liveType 为 10，表示点播，只需获取一次
//                    System.out.println("点播事件，只获取一次 HLS 地址");
//                    simulateLiveStreamUpdates(hlsUrl, liveId);
//                } else {
//                    System.out.println("未知的 liveType: " + liveType);
//                }
//                return hlsUrl;
            } else {
                // 请求失败，返回错误信息
                return "请求失败: " + jsonNode.get("msg").asText();
            }
        } catch (Exception e) {
            e.printStackTrace();
            return "获取直播信息时发生错误";
        }
        return null;
    }

    /**
     * 模拟直播过程中的更新，每分钟检查一次 m3u8 文件
     */
    private void simulateLiveStreamUpdates(String hlsUrl, long liveId) {
        /**
         * m3u8链接不变，不需要下载
         */
//            String lastM3U8Content = hlsUrl;
//            while (true) {
//                System.out.println("每分钟检查一次 m3u8 文件...");
//                JsonNode currentJsonNode = getJsonNode(liveId);
//                // 检查 m3u8 文件是否更新
//                String currentM3U8Content = currentJsonNode.get("value").get("urlGroup").get("hlsUrl").asText();
//                if (!currentM3U8Content.equals(lastM3U8Content)) {
//                    System.out.println("m3u8 文件已更新，重新下载流...");
//                    lastM3U8Content = currentM3U8Content;
//                }
//
//                // 每分钟检查一次
//                startFFmpeg(currentM3U8Content, liveId);
//                Thread.sleep(60000); // 每分钟检查一次
//            }
        startFFmpeg(hlsUrl, liveId);
    }

    /**
     * 启动 FFmpeg 下载流，并根据 existLive 判断是否继续下载
     */
    private void startFFmpeg(String hlsUrl, long liveId) {
        System.out.println("开启FFmpeg下载");
        String filename = String.valueOf(System.currentTimeMillis());
        String outputpath = "E:\\Asomething\\" + filename + ".m3u8"; // 保存为 m3u8 格式
        String ffmpegPath = "D:\\AJAVAApp\\ffmpeg\\bin\\ffmpeg.exe";
        String[] command = {
                ffmpegPath, "-i", hlsUrl, "-c", "copy", outputpath
        };
        ProcessBuilder processBuilder = new ProcessBuilder(command);
        Process process = null;

        try {
            process = processBuilder.start();

            // 检查 existLive 的状态
            boolean isLive = checkExistLive(liveId);

            while (isLive) {
                // 读取标准输出的线程
                Process finalProcess = process;
                Thread outputThread = new Thread(() -> {
                    try (BufferedReader reader = new BufferedReader(new InputStreamReader(finalProcess.getInputStream()))) {
                        String line;
                        while ((line = reader.readLine()) != null) {
                            System.out.println("FFmpeg Output: " + line);  // 输出 FFmpeg 的标准输出
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        stopFFmpeg(finalProcess);  // 捕获到IOException时，停止FFmpeg进程
                    }
                });
                outputThread.start();

                // 读取错误输出的线程
                Process finalProcess1 = process;
                Thread errorThread = new Thread(() -> {
                    try (BufferedReader errorReader = new BufferedReader(new InputStreamReader(finalProcess1.getErrorStream()))) {
                        String line;
                        while ((line = errorReader.readLine()) != null) {
                            System.err.println("FFmpeg Error: " + line);  // 输出 FFmpeg 的错误输出
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        stopFFmpeg(finalProcess1);  // 捕获到IOException时，停止FFmpeg进程
                    }
                });
                errorThread.start();
                System.out.println("存在直播，继续下载...");
                Thread.sleep(1000); // 每秒下载一次

                // 检查是否继续下载
                isLive = checkExistLive(liveId); // 每秒检查一次 existLive 状态

                // 如果检测到网络或其他错误情况，可以决定停止下载
                if (!isLive) {
                    System.out.println("直播结束，停止下载");
                    break;
                }
            }

            // 确保 FFmpeg 进程结束
            stopFFmpeg(process);
            System.out.println("直播结束，停止下载");

        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
            if (process != null) {
                stopFFmpeg(process);  // 捕获到异常时，停止FFmpeg进程
            }
        }
    }

    /**
     * 停止 FFmpeg 进程
     */
    private void stopFFmpeg(Process process) {
        if (process != null) {
            try {
                process.destroy();  // 停止 FFmpeg 进程
                System.out.println("FFmpeg 进程已停止");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 检查直播是否存在，获取 existLive 状态
     */
    private boolean checkExistLive(long liveId) throws IOException {
        JsonNode jsonNode = getJsonNode(liveId);
        int existLive = jsonNode.get("value").get("existLive").asInt();
        return existLive == 1;
    }

    /**
     * 生成签名
     */
    private String generateSignature(String content) {
        try {
            byte[] hmacSha1 = HmacUtils.hmacSha1(APP_SECRET, content);
            return Base64.encodeBase64String(hmacSha1);
        } catch (Exception e) {
            System.err.println("签名生成失败: " + e.getMessage());
            return null;
        }
    }
}